#pragma once
#include "ImportExport.h"

namespace ja2
{
	//! Basic exception.
	class BasicException : public std::exception
	{
		// Attributes
	private:
		//! Description.
		std::string const m_Desc;

		// Operations
	public:
		JA2_CORE_API virtual const char* what() const throw();

		// Operators
	private:
		BasicException &operator=(BasicException const &Right);

		// Construction/Destruction
	protected:
		BasicException(std::string const& Description);
		virtual ~BasicException() = 0 {}
	};

	//! Invalid UTF8.
	class InvalidUtf8 : public BasicException
	{
		// Construction/Destruction
	public:
		JA2_CORE_API InvalidUtf8(std::string const &Message);
	};

	//! File parsing exception.
	class FileParsingException : public BasicException
	{
		// Construction/Destruction
	public:
		JA2_CORE_API FileParsingException(std::string const &Error);
	};

	//! Unspecified runtime error.
	class RuntimeException : public BasicException
	{
		// Construction/Destruction
	public:
		JA2_CORE_API RuntimeException(std::string const &Error);
	};

	//! File not found exception.
	class FileNotFoundException : public BasicException
	{
		// Attributes
	private:
		//! File name.
		std::string const m_File;

		// Operations
	public:
		//! Get file name.
		JA2_CORE_API std::string const &get_file_name() const;

		// Construction/Destruction
	public:
		JA2_CORE_API FileNotFoundException(std::string const &Error, std::string const &File);
	};

	//! Function unimplemented.
	class UnimplementedException : public BasicException
	{
		// Construction/Destruction
	public:
		JA2_CORE_API UnimplementedException(std::string const &Error);
	};

	/*
	void logException(BasicException const& ex);

	#ifdef WIN32
	#define _FUNCTION_FORMAT_		__FUNCTION__
	#else
	//#define _FUNCTION_FORMAT_		__FUNCTION__
	#define _FUNCTION_FORMAT_		__PRETTY_FUNCTION__
	#endif

	#define THROWEXCEPTION(message) throw BasicException((message), _FUNCTION_FORMAT_, __LINE__, __FILE__, NULL)
	#define RETHROWEXCEPTION(message,ex) throw BasicException((message), _FUNCTION_FORMAT_, __LINE__, __FILE__, (ex))

	#define THROWIFFALSE(boolexpr,message) if(!(boolexpr)){THROWEXCEPTION((message));}

	#define TRYCATCH_RETHROW(expr,message) \
	{ \
		try { (expr); } \
		catch(BasicException &ex){ throw BasicException((message),_FUNCTION_FORMAT_,__LINE__,__FILE__,&ex); } \
	}

	#define IGNOREEXCEPTION(expr) \
	{ \
		try{ (expr); } \
		catch(BasicException& ex){ logException(ex); } \
	}
	*/
} /*ja2*/
